/*
 * logout-dialog.c
 *
 * Routines to create logout, shutdown, and ctl-alt-del dialogs
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.
 *
 * Authors:
 *		Calvin Gaisford <cgaisford@novell.com>
 *
 * Authors for code taken from gnome-panel-logout:
 *		Vincent Untz <vuntz@gnome.org>
 *
 * Authors for code taken from gnome-session-logout:
 *		Owen Taylor <otaylor@redhat.com>
 */


#include <config.h>

#include <string.h>
#include <stdlib.h>

#include <gtk/gtk.h>
#include <gtk/gtkinvisible.h>
#include <gdk/gdkx.h>

#include <X11/Xlib.h>
#include <X11/Xatom.h>

#include <gconf/gconf-client.h>

#include <libgnome/libgnome.h>
#include <libgnomeui/libgnomeui.h>

#include "gnome-session-code/gsm-multiscreen.h"
#include "gnome-session-code/gdm-logout-action.h"
#include "gnome-session-code/panel-power-manager.h"

#include "libssui.h"
#include "screen-fade.h"

#define SSUI_OPTION_LOGOUT			0x0001
#define SSUI_OPTION_SHUTDOWN		0x0002
#define SSUI_OPTION_RESTART			0x0004
#define SSUI_OPTION_SLEEP			0x0008
#define SSUI_OPTION_HIBERNATE		0x0010
#define SSUI_OPTION_SWITCH			0x0020
#define SSUI_OPTION_LOCK			0x0040

enum
{
	GS_RESPONSE_LOGOUT,
	GS_RESPONSE_SHUTDOWN,
	GS_RESPONSE_RESTART,
	GS_RESPONSE_SLEEP,
	GS_RESPONSE_HIBERNATE,
	GS_RESPONSE_SWITCH,
	GS_RESPONSE_LOCK
};

static gboolean ssui_show_logout_ui(gint dlg_option, 
									gchar *dlgTitle,
									gchar *dlgIconName);
static GtkWidget *ssui_get_tile(GtkWidget *image, const gchar *title,
												const gchar *desc);
static void logout_button_clicked(GtkButton *button, gpointer user_data);
static void shutdown_button_clicked(GtkButton *button, gpointer user_data);
static void restart_button_clicked(GtkButton *button, gpointer user_data);
static void lock_button_clicked(GtkButton *button, gpointer user_data);
static void sleep_button_clicked(GtkButton *button, gpointer user_data);
static void hibernate_button_clicked(GtkButton *button, gpointer user_data);
static void switch_button_clicked(GtkButton *button, gpointer user_data);

static gboolean logout_dialog_callback (GtkWidget *dialog);

static gboolean logout_dialog_configure_cb( GtkWidget *widget,
											GdkEventConfigure *event,
											gpointer data);
static gboolean logout_dialog_focus_out_cb( GtkWidget *widget,
									GdkEventFocus *event,
									gpointer data);

static GtkWidget *make_alert_widget (const char *title, const char *desc)
{
	GtkWidget *label;
	char *full;

	full = g_strdup_printf ("<span weight=\"bold\">%s</span>\n\n%s", 
			title, desc);
	label = gtk_label_new (full);
	g_free (full);

	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
	gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
	gtk_label_set_line_wrap(GTK_LABEL (label), TRUE);

	return label;
}


static void ssui_request_logout (void)
{
	GnomeClient *client;
	static int   recursion_guard = 0;

	if (recursion_guard)
		return;

	recursion_guard++;

	if (!(client = gnome_master_client ()))
		return;

	/* Only request a Global save. We only want a Local
	 * save if the user selects 'Save current setup'
	 * from the dialog.
	 */
	gnome_client_request_save (client,
			GNOME_SAVE_GLOBAL,
			TRUE,
			GNOME_INTERACT_ANY,
			TRUE, /* do not use the gnome-session gui */
			TRUE);

	recursion_guard--;
}

gboolean ssui_logout_ui()
{
	return ssui_show_logout_ui(	SSUI_OPTION_LOGOUT | 
								SSUI_OPTION_SWITCH,
								_("Log Out"),
								"gnome-logout");
}

gboolean ssui_shutdown_ui()
{
	return ssui_show_logout_ui(	SSUI_OPTION_SHUTDOWN |
								SSUI_OPTION_RESTART |
								SSUI_OPTION_SLEEP |
								SSUI_OPTION_HIBERNATE,
								_("Shutdown"),
								"gnome-shutdown");
}

gboolean ssui_downout_ui()
{
	return ssui_show_logout_ui(	SSUI_OPTION_LOGOUT | 
								SSUI_OPTION_SHUTDOWN |
								SSUI_OPTION_RESTART |
								SSUI_OPTION_LOCK,
								_("Log Out"),
								"gnome-logout");
}

static gboolean ssui_show_logout_ui(gint dlg_option, 
									gchar *dlgTitle,
									gchar *dlgIconName)
{
	GtkWidget *logoutDlg;
	GtkWidget *title;
	GtkWidget *vbox;
	GtkWidget *image;
	GtkWidget *tile;
	gint response;
	GtkWidget *invisible;
	GtkIconTheme *iconTheme;
	GdkPixbuf *themePixbuf = NULL;
	GdkWindow	*fadeWindow;
	gboolean retval = FALSE;
	gboolean showDialog = FALSE;
	PanelPowerManager *powerManager;
	gboolean a11y_enabled;
	GError *error = NULL;
	GdkScreen *screen;
//	GdkWindow	*parent;
	int monitor = 0;
	int selected_option;

	//	gsm_verbose ("display_gui: showing logout dialog\n");

	/* It's really bad here if someone else has the pointer
	 * grabbed, so we first grab the pointer and keyboard
	 * to an offscreen window, and then once we have the
	 * server grabbed, move that to our dialog.
	 */
	gtk_rc_reparse_all ();

	powerManager = panel_get_power_manager ();
	if(powerManager == NULL)
		return FALSE;

	screen = gsm_locate_screen_with_pointer (&monitor);
	if (!screen)
		screen = gdk_screen_get_default ();

	invisible = gtk_invisible_new_for_screen (screen);

	gtk_widget_show (invisible);

	a11y_enabled = GTK_IS_ACCESSIBLE (gtk_widget_get_accessible (invisible));

	logoutDlg = g_object_new (GTK_TYPE_DIALOG,
			"type", GTK_WINDOW_TOPLEVEL,
			NULL);

	/* Only create a managed window if a11y is enabled */
	if (a11y_enabled)
	{
		atk_object_set_role (gtk_widget_get_accessible (logoutDlg), 
									ATK_ROLE_ALERT);
	}

	gtk_window_set_decorated (GTK_WINDOW (logoutDlg), TRUE);
	gtk_window_set_title (GTK_WINDOW (logoutDlg), dlgTitle);
	gtk_window_set_icon_name(GTK_WINDOW(logoutDlg), dlgIconName);
	gtk_dialog_set_has_separator (GTK_DIALOG (logoutDlg), FALSE);

	// setup specs from Gnome HIG
	gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (logoutDlg)->vbox), 12);
	gtk_container_set_border_width (GTK_CONTAINER(logoutDlg), 6);

	vbox = gtk_vbox_new (FALSE, 12);
	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (logoutDlg)->vbox), vbox, 
										FALSE, FALSE, 0);
	gtk_container_set_border_width(GTK_CONTAINER (vbox), 6);
	gtk_widget_show (vbox);

	gtk_window_set_screen (GTK_WINDOW (logoutDlg), screen);
	gtk_window_set_policy (GTK_WINDOW (logoutDlg), FALSE, FALSE, TRUE);
	gtk_window_set_keep_above(GTK_WINDOW(logoutDlg), TRUE);
	gtk_window_stick(GTK_WINDOW(logoutDlg));

	iconTheme = gtk_icon_theme_get_for_screen(screen);

	// add help button in every case
	gtk_dialog_add_button (GTK_DIALOG (logoutDlg), GTK_STOCK_HELP, 
			GTK_RESPONSE_HELP);

	gtk_dialog_add_button (GTK_DIALOG (logoutDlg), 
						GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);

	if(dlg_option & SSUI_OPTION_LOGOUT)
	{
		image = NULL;
		if(gtk_icon_theme_has_icon(iconTheme, "system-log-out"))
		{
			themePixbuf = gtk_icon_theme_load_icon(iconTheme,
					"system-log-out", 48, 0, &error);
			if(themePixbuf != NULL)
				image = gtk_image_new_from_pixbuf(themePixbuf);
			else
				image = NULL;
		}
		else if(gtk_icon_theme_has_icon(iconTheme, "gnome-logout"))
		{
			themePixbuf = gtk_icon_theme_load_icon(iconTheme,
					"gnome-logout", 48, 0, &error);
			if(themePixbuf != NULL)
				image = gtk_image_new_from_pixbuf(themePixbuf);
			else
				image = NULL;
		}
		if(image == NULL)
		{
			image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_QUESTION,
					GTK_ICON_SIZE_DIALOG);
		}
		tile = ssui_get_tile(image, _("_Log Out"),
				_("Ends your session and logs you out."));
		g_signal_connect (G_OBJECT (tile), "clicked",
				G_CALLBACK (logout_button_clicked), logoutDlg);

		gtk_box_pack_start (GTK_BOX (vbox), tile, TRUE, TRUE, 0);
		gtk_widget_show_all(tile);
	}



	if(dlg_option & SSUI_OPTION_LOCK)
	{
		image = NULL;
		if(gtk_icon_theme_has_icon(iconTheme, "system-lock-screen"))
		{
			themePixbuf = gtk_icon_theme_load_icon(iconTheme,
					"system-lock-screen", 48, 0, &error);
			if(themePixbuf != NULL)
				image = gtk_image_new_from_pixbuf(themePixbuf);
			else
				image = NULL;
		}
		else if(gtk_icon_theme_has_icon(iconTheme, "gnome-lockscreen"))
		{
			themePixbuf = gtk_icon_theme_load_icon(iconTheme,
					"gnome-lockscreen", 48, 0, &error);
			if(themePixbuf != NULL)
				image = gtk_image_new_from_pixbuf(themePixbuf);
			else
				image = NULL;
		}
		if(image == NULL)
		{
			image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_QUESTION,
					GTK_ICON_SIZE_DIALOG);
		}
		tile = ssui_get_tile(image, _("Loc_k Screen"),
				_("Locks this computer's screen."));
		g_signal_connect (G_OBJECT (tile), "clicked",
				G_CALLBACK (lock_button_clicked), logoutDlg);

		gtk_box_pack_start (GTK_BOX (vbox), tile, TRUE, TRUE, 0);
		gtk_widget_show_all(tile);
	}



	if(dlg_option & SSUI_OPTION_SHUTDOWN)
	{
		image = NULL;
		if(gtk_icon_theme_has_icon(iconTheme, "system-shutdown"))
		{
			themePixbuf = gtk_icon_theme_load_icon(iconTheme,
					"system-shutdown", 48, 0, &error);
			if(themePixbuf != NULL)
				image = gtk_image_new_from_pixbuf(themePixbuf);
			else
				image = NULL;
		}
		else if(gtk_icon_theme_has_icon(iconTheme, "gnome-shutdown"))
		{
			themePixbuf = gtk_icon_theme_load_icon(iconTheme,
					"gnome-shutdown", 48, 0, &error);
			if(themePixbuf != NULL)
				image = gtk_image_new_from_pixbuf(themePixbuf);
			else
				image = NULL;
		}
		if(image == NULL)
		{
			image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_QUESTION,
					GTK_ICON_SIZE_DIALOG);
		}
		tile = ssui_get_tile(image, _("_Shutdown"),
				_("Ends your session and turns off the computer."));
		g_signal_connect (G_OBJECT (tile), "clicked",
				G_CALLBACK (shutdown_button_clicked), logoutDlg);

		if(!gdm_supports_logout_action (GDM_LOGOUT_ACTION_SHUTDOWN))
		{
			gtk_widget_set_sensitive(tile, FALSE);
		}

		gtk_box_pack_start (GTK_BOX (vbox), tile, TRUE, TRUE, 0);
		gtk_widget_show_all(tile);
	}



	if(dlg_option & SSUI_OPTION_RESTART)
	{
		image = NULL;
		if(gtk_icon_theme_has_icon(iconTheme, "stock_refresh"))
		{
			themePixbuf = gtk_icon_theme_load_icon(iconTheme,
					"stock_refresh", 48, 0, &error);
			if(themePixbuf != NULL)
				image = gtk_image_new_from_pixbuf(themePixbuf);
			else
				image = NULL;
		}
		else if(gtk_icon_theme_has_icon(iconTheme, "gnome-reboot"))
		{
			themePixbuf = gtk_icon_theme_load_icon(iconTheme,
					"gnome-reboot", 48, 0, &error);
			if(themePixbuf != NULL)
				image = gtk_image_new_from_pixbuf(themePixbuf);
			else
				image = NULL;
		}
		if(image == NULL)
		{
			image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_QUESTION,
					GTK_ICON_SIZE_DIALOG);
		}
		tile = ssui_get_tile(image, _("_Restart"),
				_("Ends your session and restarts the computer."));
		g_signal_connect (G_OBJECT (tile), "clicked",
				G_CALLBACK (restart_button_clicked), logoutDlg);

		if(!gdm_supports_logout_action (GDM_LOGOUT_ACTION_REBOOT))
		{
			gtk_widget_set_sensitive(tile, FALSE);
		}

		gtk_box_pack_start (GTK_BOX (vbox), tile, TRUE, TRUE, 0);
		gtk_widget_show_all(tile);
	}



	if(dlg_option & SSUI_OPTION_SLEEP)
	{
		image = NULL;
		if(gtk_icon_theme_has_icon(iconTheme, "sleep"))
		{
			themePixbuf = gtk_icon_theme_load_icon(iconTheme,
					"sleep", 48, 0, &error);
			if(themePixbuf != NULL)
				image = gtk_image_new_from_pixbuf(themePixbuf);
			else
				image = NULL;
		}
		if(image == NULL)
		{
			image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_QUESTION,
					GTK_ICON_SIZE_DIALOG);
		}
		tile = ssui_get_tile(image, _("Slee_p"),
				_("Suspends your session quickly, using minimal power while the computer stands by."));
		g_signal_connect (G_OBJECT (tile), "clicked",
				G_CALLBACK (sleep_button_clicked), logoutDlg);

		if(!panel_power_manager_can_suspend(powerManager))
		{
			gtk_widget_set_sensitive(tile, FALSE);
		}

		gtk_box_pack_start (GTK_BOX (vbox), tile, TRUE, TRUE, 0);
		gtk_widget_show_all(tile);
	}


	if(dlg_option & SSUI_OPTION_HIBERNATE)
	{
		image = NULL;
		if(gtk_icon_theme_has_icon(iconTheme, "drive-harddisk"))
		{
			themePixbuf = gtk_icon_theme_load_icon(iconTheme,
					"drive-harddisk", 48, 0, &error);
			if(themePixbuf != NULL)
				image = gtk_image_new_from_pixbuf(themePixbuf);
			else
				image = NULL;
		}
		if(image == NULL)
		{
			image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_QUESTION,
					GTK_ICON_SIZE_DIALOG);
		}
		tile = ssui_get_tile(image, _("Hi_bernate"),
				_("Suspends your session, using no power until the computer is restarted."));
		g_signal_connect (G_OBJECT (tile), "clicked",
				G_CALLBACK (hibernate_button_clicked), logoutDlg);

		if(!panel_power_manager_can_hibernate(powerManager))
		{
			gtk_widget_set_sensitive(tile, FALSE);
		}

		gtk_box_pack_start (GTK_BOX (vbox), tile, TRUE, TRUE, 0);
		gtk_widget_show_all(tile);
	}


	if(dlg_option & SSUI_OPTION_SWITCH)
	{
		image = NULL;
		if(gtk_icon_theme_has_icon(iconTheme, "config-users"))
		{
			themePixbuf = gtk_icon_theme_load_icon(iconTheme,
					"config-users", 48, 0, &error);
			if(themePixbuf != NULL)
				image = gtk_image_new_from_pixbuf(themePixbuf);
			else
				image = NULL;
		}
		if(image == NULL)
		{
			image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_QUESTION,
					GTK_ICON_SIZE_DIALOG);
		}
		tile = ssui_get_tile(image, _("S_witch User"),
				_("Suspends your session, allowing another user to log in and use the computer."));
		g_signal_connect (G_OBJECT (tile), "clicked",
				G_CALLBACK (switch_button_clicked), logoutDlg);

		gtk_box_pack_start (GTK_BOX (vbox), tile, TRUE, TRUE, 0);
		gtk_widget_show_all(tile);
	}
	
	gtk_dialog_set_default_response (GTK_DIALOG (logoutDlg), 
						GTK_RESPONSE_CANCEL);

	gsm_center_window_on_screen (GTK_WINDOW (logoutDlg), screen, monitor);

	if (!a11y_enabled)
	{
		// start fading of other screens
		gsm_foreach_screen (ssui_fadeout_screen);
	}

	gtk_widget_show_all(logoutDlg);

	/*	setup properties for window manager to special case the
		dialog (compiz does some awesome fading here) */
	{
		Display *xdisplay = GDK_WINDOW_XDISPLAY (logoutDlg->window);
		Window  xwindow = GDK_WINDOW_XID (logoutDlg->window);
		Atom    state_atom, display_modal_atom;

		state_atom = XInternAtom (xdisplay, "_NET_WM_STATE", 0);
		display_modal_atom = XInternAtom (xdisplay,
				"_NET_WM_STATE_DISPLAY_MODAL", 0);
	
		XChangeProperty (xdisplay,
				xwindow,
				state_atom,
				XA_ATOM, 32, PropModeAppend,
				(guchar *) &display_modal_atom, 1);
	}

	if(!a11y_enabled)
	{
		// adds a callback to start the fading of all windows after
		// the primary display is captured and the logout dialog is
		// shown
		g_idle_add ((GSourceFunc) logout_dialog_callback, logoutDlg);

		g_signal_connect (G_OBJECT(GTK_WIDGET(logoutDlg)), "configure-event",
				G_CALLBACK (logout_dialog_configure_cb),
				NULL);

		g_signal_connect (G_OBJECT(GTK_WIDGET(logoutDlg)), "focus-out-event",
				G_CALLBACK (logout_dialog_focus_out_cb),
				NULL);
	}

	do
	{

	response = gtk_dialog_run (GTK_DIALOG (logoutDlg));

	showDialog = FALSE;

	switch(response)
	{
		case GS_RESPONSE_LOGOUT:
			gdm_set_logout_action (GDM_LOGOUT_ACTION_NONE);
			ssui_request_logout();
			break;
		case GS_RESPONSE_SWITCH:
			showDialog = !ssui_switch_user_dialog(screen, monitor, 
													a11y_enabled);
			break;
		case GS_RESPONSE_SHUTDOWN:
			gdm_set_logout_action (GDM_LOGOUT_ACTION_SHUTDOWN);
			ssui_request_logout();
			break;
		case GS_RESPONSE_RESTART:
			gdm_set_logout_action (GDM_LOGOUT_ACTION_REBOOT);
			ssui_request_logout();
			break;
		case GS_RESPONSE_HIBERNATE:
			panel_power_manager_attempt_hibernate (powerManager);
			//g_spawn_command_line_async ("powersave --suspend-to-disk", NULL);
			break;
		case GS_RESPONSE_SLEEP:
			panel_power_manager_attempt_suspend (powerManager);
			//g_spawn_command_line_async ("powersave --suspend-to-ram", NULL);
			break;
		case GS_RESPONSE_LOCK:
			g_spawn_command_line_async(
								"gnome-screensaver-command --lock", NULL);
			//g_spawn_command_line_async ("powersave --suspend-to-ram", NULL);
			break;
		case GTK_RESPONSE_HELP:
			gnome_help_display_desktop_on_screen(NULL, "user-guide",
					"user-guide.xml",
					"gosgetstarted-73",
					screen,
					&error);

			if (error) 
			{
				GtkWidget *dialog;

				dialog = gtk_message_dialog_new (NULL,
						GTK_DIALOG_DESTROY_WITH_PARENT,
						GTK_MESSAGE_ERROR,
						GTK_BUTTONS_CLOSE,
						("There was an error displaying help: \n%s"),
						error->message);

				g_signal_connect (G_OBJECT (dialog), "response",
						G_CALLBACK (gtk_widget_destroy),
						NULL);

				gtk_window_set_screen (GTK_WINDOW (dialog), screen);

				gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
				gtk_widget_show (dialog);
				g_error_free (error);
			}

			retval = FALSE;
			break;
		case GTK_RESPONSE_NONE:
		case GTK_RESPONSE_DELETE_EVENT:
		case GTK_RESPONSE_CANCEL:
			break;
		default:
			g_assert_not_reached();
	}

	}while(showDialog);

	gtk_widget_destroy (logoutDlg);
	gtk_widget_destroy (invisible);


	if (!a11y_enabled)
	{
		ssui_hide_fadeout_windows ();
		/* XUngrabServer (GDK_DISPLAY ()); */

		gdk_flush ();
	}

	return retval;
}

static gboolean logout_dialog_callback (GtkWidget *dialog)
{
	XSetInputFocus (GDK_DISPLAY (),
			GDK_WINDOW_XWINDOW (dialog->window),
			RevertToParent,
			CurrentTime);

	return FALSE;
}

static gboolean logout_dialog_configure_cb( GtkWidget *widget,
									GdkEventConfigure *event,
									gpointer data)
{
	ssui_punch_hole_fadeout_windows(GTK_WINDOW(widget));
	return FALSE;
}

static gboolean logout_dialog_focus_out_cb( GtkWidget *widget,
									GdkEventFocus *event,
									gpointer data)
{
	if(event->in == FALSE)
	{
		XSetInputFocus (GDK_DISPLAY (),
			GDK_WINDOW_XWINDOW (widget->window),
			RevertToParent,
			CurrentTime);
	}

	return FALSE;
}

static void logout_button_clicked(GtkButton *button, gpointer user_data)
{
	gtk_dialog_response(GTK_DIALOG(user_data), GS_RESPONSE_LOGOUT);
}

static void shutdown_button_clicked(GtkButton *button, gpointer user_data)
{
	gtk_dialog_response(GTK_DIALOG(user_data), GS_RESPONSE_SHUTDOWN);
}

static void restart_button_clicked(GtkButton *button, gpointer user_data)
{
	gtk_dialog_response(GTK_DIALOG(user_data), GS_RESPONSE_RESTART);
}

static void lock_button_clicked(GtkButton *button, gpointer user_data)
{
	gtk_dialog_response(GTK_DIALOG(user_data), GS_RESPONSE_LOCK);
}

static void sleep_button_clicked(GtkButton *button, gpointer user_data)
{
	gtk_dialog_response(GTK_DIALOG(user_data), GS_RESPONSE_SLEEP);
}

static void hibernate_button_clicked(GtkButton *button, gpointer user_data)
{
	gtk_dialog_response(GTK_DIALOG(user_data), GS_RESPONSE_HIBERNATE);
}

static void switch_button_clicked(GtkButton *button, gpointer user_data)
{
	gtk_dialog_response(GTK_DIALOG(user_data), GS_RESPONSE_SWITCH);
}

static GtkWidget *ssui_get_tile(GtkWidget *image, const gchar *title,
												const gchar *desc)
{
	GtkWidget	*button;
	GtkWidget	*widget;
	GtkWidget	*alignment;
	GtkWidget	*hbox;
	GtkWidget	*vbox;

	g_assert(title != NULL);

	button = GTK_WIDGET(gtk_button_new());
	gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
//	GTK_WIDGET_UNSET_FLAGS(button, GTK_HAS_FOCUS);

	alignment = gtk_alignment_new(0, 0.5, 0, 0);
	gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 6, 6);
	gtk_container_add(GTK_CONTAINER(button), alignment);

	hbox = gtk_hbox_new(FALSE, 12);
	gtk_container_add(GTK_CONTAINER(alignment), hbox);
	if(image != NULL)
		gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0);

	vbox = gtk_vbox_new(FALSE, 2);

	if(title != NULL)
	{
		gchar *full;
		GtkWidget *label;

		full = g_strdup_printf ("<span weight=\"bold\">%s</span>", title);
		label = gtk_label_new(full);
		g_free (full);

		gtk_label_set_use_markup (GTK_LABEL(label), TRUE);
		gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
		gtk_label_set_use_underline(GTK_LABEL(label), TRUE);

		gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
	}

	if(desc != NULL)
	{
		gchar *full;
		GtkWidget *label;

		full = g_strdup_printf ("<span foreground=\"#777777\">%s</span>", 
									desc);
		label = gtk_label_new(full);
		g_free (full);

		gtk_label_set_use_markup (GTK_LABEL(label), TRUE);
		gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
		gtk_label_set_use_underline(GTK_LABEL(label), TRUE);
		gtk_label_set_line_wrap(GTK_LABEL (label), TRUE);

		gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
	}

	gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);

	return button;
}


